
//
// 121226 - AH - Created.
// 121231 - AH - update() and tool bar button to invoke update(). 
//

package org.japril.swing.jutil.logging;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.japril.jutil.logging.ControlLogSink;
import org.japril.jutil.logging.ControlLogSink.ClassLogInfo;
import org.japril.jutil.logging.PrintLogSink;

/**
 * <p>
 *   Panel to view and control a
 *   {@link ControlLogSink}.
 * </p>
 * @author Arne Halvorsen (AH)
 */
@SuppressWarnings("serial")
public final class ControlLogSinkPanel extends JPanel
{
  private final JTable m_sTable=
    new JTable(ControlLogSinkTableModel.EMPTY_MODEL);
  
  private final JTable m_cTable=
    new JTable(ControlLogSinkClassInfoTableModel.EMPTY_MODEL);
  
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public ControlLogSinkPanel()
  {
    setLayout(new BorderLayout());
    
    m_sTable.getSelectionModel().setSelectionMode(
      ListSelectionModel.SINGLE_SELECTION);
    m_cTable.getSelectionModel().setSelectionMode(
      ListSelectionModel.SINGLE_SELECTION);
    
    m_sTable.getSelectionModel().addListSelectionListener
    (
      new ListSelectionListener()
      {
        public void valueChanged(ListSelectionEvent e)
        {
          int row=m_sTable.getSelectedRow();
          if (row==-1)
          {
            m_cTable.setModel(ControlLogSinkClassInfoTableModel.EMPTY_MODEL);
          }
          else
          {
            ControlLogSinkTableModel m=(ControlLogSinkTableModel)
              m_sTable.getModel();
            ClassLogInfo cli=m.getClassLogInfo(row);
            m_cTable.setModel(new ControlLogSinkClassInfoTableModel(cli));
          }
        }
      }
    );
    
    JSplitPane sp=new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    m_sTable.setAutoCreateRowSorter(true);
    sp.setLeftComponent(new JScrollPane(m_sTable));
    sp.setRightComponent(new JScrollPane(m_cTable));
    sp.setDividerLocation(300);
    
    makeToolBar();
    
    add(sp, BorderLayout.CENTER);
  }
  
  private LogAction m_logAction;
  
  private void makeToolBar()
  {
    JToolBar bar=new JToolBar();
    
    JCheckBox cb=new JCheckBox();
    m_logAction=new LogAction(cb);
    cb.setAction(m_logAction);
    bar.add(cb);
    
    bar.add(m_updateAction);
    bar.add(m_controlLogSinksDialogAction);
    
    add(bar, BorderLayout.NORTH);
  }
  
  private abstract class ControlAction extends AbstractAction
  {
    public ControlAction(String name)
    {
      super(name);
      setEnabled(false);
    }
    
    boolean update()
    {
      //boolean retVal=m_current instanceof ControlLogSink;
      ControlLogSink cls=ControlLogSinks.getInstance().getCurrentSink();
      if (cls!=null)
      {
        setEnabled(true);
        return true;
      }
      return false;
    }
  }
  
  
  private final class LogAction extends ControlAction
  {
    private final JCheckBox m_cb;
    
    public LogAction(JCheckBox cb)
    {
      super("Log");
      m_cb=cb;
    }
    
    public void actionPerformed(ActionEvent e)
    {
      JCheckBox cb=(JCheckBox)e.getSource();
      ControlLogSink cls=getControlLogSink();
      if (cls!=null)
      {
        cls.log(cb.isSelected());
      }
    }
    
    boolean update()
    {
      boolean retVal=super.update();
      ControlLogSink cls=getControlLogSink();
      m_cb.setSelected(cls.log());
      return retVal;
    }
    
  }
  
  private ControlLogSinksDialog m_sinksDlg=null;
  
  private Action m_controlLogSinksDialogAction=new AbstractAction("Config")
  {
    public void actionPerformed(ActionEvent e)
    {
      if (m_sinksDlg==null) m_sinksDlg=new ControlLogSinksDialog();
      m_sinksDlg.showDialog();
    }
  };
  
  private final Action m_updateAction=new AbstractAction("Update")
  {
    public void actionPerformed(ActionEvent e){ update(); }
  };
  
  /**
   * <p>
   *   Set content.
   * </p>
   * @param ls Sink to set. If is not a 
   *           {@link PrintLogSink} or {@code null} clears.
   */
  /*
  public void setSink(LogSink ls)
  {
    if (ls==m_current) return;
    
    m_current=ls;
    
    update();
  }
  */
  
  private static ControlLogSink getControlLogSink()
  {
    return ControlLogSinks.getInstance().getCurrentSink();
  }
  
  /**
   * <p>
   *   Updates view.
   * </p>
   */
  public void update()
  {
    ControlLogSink cls=getControlLogSink();
      
    if (cls==null) 
    {
      m_sTable.setModel(ControlLogSinkTableModel.EMPTY_MODEL);
    }
    else           
    {
      m_sTable.setModel(new ControlLogSinkTableModel(cls));
    }

    m_logAction.update();
  }
  
}
